package de.sabram.upb.specs.serializer;

import com.google.inject.Inject;
import com.google.inject.Provider;
import de.sabram.upb.specs.ptg.Argument;
import de.sabram.upb.specs.ptg.FunctionCall;
import de.sabram.upb.specs.ptg.Insertion;
import de.sabram.upb.specs.ptg.Item;
import de.sabram.upb.specs.ptg.Optional;
import de.sabram.upb.specs.ptg.PTGSpec;
import de.sabram.upb.specs.ptg.PatternBody;
import de.sabram.upb.specs.ptg.PatternSpec;
import de.sabram.upb.specs.ptg.PtgPackage;
import de.sabram.upb.specs.ptg.Type;
import de.sabram.upb.specs.services.PtgGrammarAccess;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.serializer.acceptor.ISemanticSequenceAcceptor;
import org.eclipse.xtext.serializer.acceptor.SequenceFeeder;
import org.eclipse.xtext.serializer.diagnostic.ISemanticSequencerDiagnosticProvider;
import org.eclipse.xtext.serializer.diagnostic.ISerializationDiagnostic.Acceptor;
import org.eclipse.xtext.serializer.sequencer.AbstractDelegatingSemanticSequencer;
import org.eclipse.xtext.serializer.sequencer.GenericSequencer;
import org.eclipse.xtext.serializer.sequencer.ISemanticNodeProvider.INodesForEObjectProvider;
import org.eclipse.xtext.serializer.sequencer.ISemanticSequencer;
import org.eclipse.xtext.serializer.sequencer.ITransientValueService;
import org.eclipse.xtext.serializer.sequencer.ITransientValueService.ValueTransient;

@SuppressWarnings("all")
public class PtgSemanticSequencer extends AbstractDelegatingSemanticSequencer {

	@Inject
	private PtgGrammarAccess grammarAccess;
	
	public void createSequence(EObject context, EObject semanticObject) {
		if(semanticObject.eClass().getEPackage() == PtgPackage.eINSTANCE) switch(semanticObject.eClass().getClassifierID()) {
			case PtgPackage.ARGUMENT:
				if(context == grammarAccess.getArgumentRule()) {
					sequence_Argument(context, (Argument) semanticObject); 
					return; 
				}
				else break;
			case PtgPackage.FUNCTION_CALL:
				if(context == grammarAccess.getFunctionCallRule()) {
					sequence_FunctionCall(context, (FunctionCall) semanticObject); 
					return; 
				}
				else break;
			case PtgPackage.INSERTION:
				if(context == grammarAccess.getInsertionRule()) {
					sequence_Insertion(context, (Insertion) semanticObject); 
					return; 
				}
				else break;
			case PtgPackage.ITEM:
				if(context == grammarAccess.getItemRule()) {
					sequence_Item(context, (Item) semanticObject); 
					return; 
				}
				else break;
			case PtgPackage.OPTIONAL:
				if(context == grammarAccess.getOptionalRule()) {
					sequence_Optional(context, (Optional) semanticObject); 
					return; 
				}
				else break;
			case PtgPackage.PTG_SPEC:
				if(context == grammarAccess.getPTGSpecRule()) {
					sequence_PTGSpec(context, (PTGSpec) semanticObject); 
					return; 
				}
				else break;
			case PtgPackage.PATTERN_BODY:
				if(context == grammarAccess.getPatternBodyRule()) {
					sequence_PatternBody(context, (PatternBody) semanticObject); 
					return; 
				}
				else break;
			case PtgPackage.PATTERN_SPEC:
				if(context == grammarAccess.getPatternSpecRule()) {
					sequence_PatternSpec(context, (PatternSpec) semanticObject); 
					return; 
				}
				else break;
			case PtgPackage.TYPE:
				if(context == grammarAccess.getTypeRule()) {
					sequence_Type(context, (Type) semanticObject); 
					return; 
				}
				else break;
			}
		if (errorAcceptor != null) errorAcceptor.accept(diagnosticProvider.createInvalidContextOrTypeDiagnostic(semanticObject, context));
	}
	
	/**
	 * Constraint:
	 *     insertion=Insertion
	 */
	protected void sequence_Argument(EObject context, Argument semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, PtgPackage.Literals.ARGUMENT__INSERTION) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, PtgPackage.Literals.ARGUMENT__INSERTION));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getArgumentAccess().getInsertionInsertionParserRuleCall_0(), semanticObject.getInsertion());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID arguments+=Argument*)
	 */
	protected void sequence_FunctionCall(EObject context, FunctionCall semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (index=INT? type=Type?)
	 */
	protected void sequence_Insertion(EObject context, Insertion semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (itemName=STRING | itemCall=FunctionCall | insertion=Insertion)
	 */
	protected void sequence_Item(EObject context, Item semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     items+=Item+
	 */
	protected void sequence_Optional(EObject context, Optional semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     ptgspecs+=PatternSpec*
	 */
	protected void sequence_PTGSpec(EObject context, PTGSpec semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     ((patternBody+=Item | patternBody+=Optional)*)
	 */
	protected void sequence_PatternBody(EObject context, PatternBody semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID patternBody=PatternBody)
	 */
	protected void sequence_PatternSpec(EObject context, PatternSpec semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, PtgPackage.Literals.PATTERN_SPEC__NAME) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, PtgPackage.Literals.PATTERN_SPEC__NAME));
			if(transientValues.isValueTransient(semanticObject, PtgPackage.Literals.PATTERN_SPEC__PATTERN_BODY) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, PtgPackage.Literals.PATTERN_SPEC__PATTERN_BODY));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getPatternSpecAccess().getNameIDTerminalRuleCall_0_0(), semanticObject.getName());
		feeder.accept(grammarAccess.getPatternSpecAccess().getPatternBodyPatternBodyParserRuleCall_2_0(), semanticObject.getPatternBody());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     (
	 *         name='char' | 
	 *         name='double' | 
	 *         name='float' | 
	 *         name='int' | 
	 *         name='long' | 
	 *         name='pointer' | 
	 *         name='short' | 
	 *         name='string'
	 *     )
	 */
	protected void sequence_Type(EObject context, Type semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
}
